using System;
using System.Collections.Generic;
using System.Text;
using DataAccess;
using Task.Contracts;
using Globals;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using NHibernate;
using NHibernate.Expression;
using System.Collections;

namespace Task
{
    public class ArtTask : IArtTask
    {
        public List<art_type> ReadArtTypes()
        {
            NHibernateDao<art_type, int> factory = new NHibernateDao<art_type, int>();
            List<art_type> list = factory.GetAll();
            return list;
        }

        public int AddArt(string name, string description, string path, string text,
            int artTypeId, user userTmp, int galleryId)
        {
            NHibernateDao<art, int> factory = new NHibernateDao<art, int>();
            art newArt = new art();

            newArt.name = name;
            newArt.date = DateTime.Now;
            newArt.description = description;
            newArt.path = path.Replace('\\','/' );
            newArt.text = text;

            NHibernateDao<art_type, int> artTypeFactory = new NHibernateDao<art_type, int>();
            art_type artType = artTypeFactory.GetById(artTypeId, false);
            newArt.art_type = artType;

            newArt.user = userTmp;

            NHibernateDao<gallery, int> galleryFactory = new NHibernateDao<gallery, int>();
            gallery galleryTmp = galleryFactory.GetById(galleryId, false);
            newArt.gallery = galleryTmp;

            factory.Save(newArt);

            return newArt.id;
        }

        public bool isPhotoExtensionAllowed(string photoExtension)
        {
            photoExtension = photoExtension.ToLower();
            List<string> allowedImageList = new List<string>(ContentNamesGlobals.allowedImage);
            return allowedImageList.Contains(photoExtension);                
        }

        public bool isBinaryExtensionAllowed(string binaryExtension)
        {
            binaryExtension = binaryExtension.ToLower();
            List<string> forbiddenBinariesList = new List<string>(ContentNamesGlobals.forbiddenBinaries);
            return !forbiddenBinariesList.Contains(binaryExtension);
        }

        public art ReadArtByArtId(int artId)
        {
            NHibernateDao<art, int> galleryFactory = new NHibernateDao<art, int>();
            return galleryFactory.GetById(artId, false);
        }

        public bool isPhotoRealFoto(Stream stream)
        {
            try
            {
                System.Drawing.Image image = System.Drawing.Image.FromStream(stream);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

 

        public System.Drawing.Image MakeMiniFoto(Stream stream)
        {
            System.Drawing.Image image = null;
            try
            {
                image = System.Drawing.Image.FromStream(stream);

                int wspolczynnikX = (int)(image.Width/150);
                int wspolczynnikY = (int)(image.Height/150);

                if (wspolczynnikX > wspolczynnikY)
                {
                    return ScaleImage(image,
                        (int)(image.Width / wspolczynnikX),
                        (int)(image.Height / wspolczynnikX)
                        );
                }
                else
                {
                    return ScaleImage(image,
                        (int)(image.Width / wspolczynnikY),
                        (int)(image.Height / wspolczynnikY)
                        );
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            return image;
        }

        /// <summary>
        /// Scale an image to a given width and height.
        /// </summary>
        /// <param name="img"></param>
        /// <param name="outputWidth"></param>
        /// <param name="outputHeight"></param>
        /// <returns></returns>
        private  static Image ScaleImage(Image img, int outputWidth, int outputHeight)
        {
            Bitmap outputImage = new Bitmap(outputWidth, outputHeight, img.PixelFormat);
            outputImage.SetResolution(img.HorizontalResolution, img.VerticalResolution);
            Graphics graphics = Graphics.FromImage(outputImage);
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.DrawImage(img, new Rectangle(0, 0, outputWidth, outputHeight),
            new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
            graphics.Dispose();
            return outputImage;
        }
        
        public void DeleteArt(int artId)
        {
            if (artId < 1)
                return;
            NHibernateDao<art, int> factory = new NHibernateDao<art, int>();
            art a = factory.GetById(artId, false);
            factory.CommitChanges();
            if(a!=null)
                factory.Delete(a);
            factory.CommitChanges();
        }

        public List<rate_type> ReadRateTypes()
        {
            NHibernateDao<rate_type, int> factory = new NHibernateDao<rate_type, int>();
            return factory.GetAll();
        }

        public void InsertRate(int userId, int rateId, int artId)
        {
            NHibernateDao<user, int> userFactory = new NHibernateDao<user, int>();
            user usetTmp = userFactory.GetById(userId,false);

            NHibernateDao<rate_type, int> rateTypeFactory = new NHibernateDao<rate_type, int>();
            rate_type rateTypeTmp = rateTypeFactory.GetById(rateId, false);

            NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();
            art artTmp = artFactory.GetById(artId,false);

            NHibernateDao<art_rate_type, int> factory = new NHibernateDao<art_rate_type, int>();
            art_rate_type rate = new art_rate_type();
            rate.user = usetTmp;
            rate.rate_type = rateTypeTmp;
            rate.art = artTmp;
            rate.date = DateTime.Now;

            factory.Save(rate);
        }

        public int ReadCountRate(int artId)
        {
            NHibernateDao<art_rate_type, int> factory = new NHibernateDao<art_rate_type, int>();
            return factory.GetByCriteria(NHibernate.Expression.Expression.Eq("art_id", artId)).Count;
        }

        public double ReadAverageRate(int artId)
        {
            NHibernateDao<art_rate_type, int> factory = new NHibernateDao<art_rate_type, int>();
            List<art_rate_type> list = factory.GetByCriteria(NHibernate.Expression.Expression.Eq("art_id", artId));

            int all = 0;
            foreach (art_rate_type a in list)
            {
                all += int.Parse(a.rate_type.val.Value.ToString());
            }

            if (list.Count == 0)
                return 0;
            return (double)(all / (double)list.Count);
            
            
        
        }

        public void WriteVisit(int artId, int userId)
        {
            if ((artId < 1) || (userId < 1))
                return;
            NHibernateDao<visit, int> factory = new NHibernateDao<visit, int>();

            NHibernateDao<user, int> userFactory = new NHibernateDao<user, int>();
            user usetTmp = userFactory.GetById(userId, false);

            NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();
            art artTmp = artFactory.GetById(artId, false);

            visit visitTmp = new visit();
            visitTmp.date = DateTime.Now;
            visitTmp.user = usetTmp;
            visitTmp.art = artTmp;

            factory.Save(visitTmp);
            factory.CommitChanges();
        }

        public int ReadVisit(int artId)
        {
            if (artId < 1)
                return 0;
            NHibernateDao<visit, int> factory = new NHibernateDao<visit, int>();
            int ret = factory.GetByCriteria(NHibernate.Expression.Expression.Eq("art_id", artId)).Count;
            factory.CommitChanges();
            return ret;

        }


        public List<art> GetLastArtForUser(int userId,int number)
        {
            NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();
            return artFactory.GetByCriteria(0, number, "date", false, NHibernate.Expression.Expression.Eq("user_id", userId));
        }

        public IList GetBestRatedForUser(int userId, int number)
        {
            ISession session = NHibernateSessionManager.Instance.GetSession();
            NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();

            IList l = session.CreateQuery("select ar.art.id,avg(ar.rate_type.id) from art_rate_type ar where ar.art.user.id = :userId group by ar.art.id, ar.art order by avg(ar.rate_type.id) desc").SetParameter("userId",userId.ToString()).SetMaxResults(number).List();
            
            foreach (object[] o in l)
            {
                o[0] = artFactory.GetById((int)o[0],false);
            }

            return l;
        }
        public List<art> ReadLastArt()
        {
            //int number = 3;

            //ISession session = NHibernateSessionManager.Instance.GetSession();
            //NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();

            //IList l =
            //session.CreateQuery("from art order by art.date desc").SetMaxResults(number).List();

            //foreach (object[] o in l)
            //{
            //    o[0] = artFactory.GetById((int)o[0], false);
            //}

            //return (List<art>)l;

            NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();
            
            return artFactory.GetByCriteria(0, 5, "date", false, NHibernate.Expression.Expression.IsNotNull("id"));

        }

        public IList ReadBestArt()
        {
            //int maxArts = 6;

            //NHibernateDao<art, int> factory = new NHibernateDao<art, int>();
            //return factory.GetByCriteria(NHibernate.Expression.Expression.Eq("art_type_id", 2));

            ISession session = NHibernateSessionManager.Instance.GetSession();
            NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();

            IList l = session.CreateQuery("select ar.art.id,avg(ar.rate_type.id) from art_rate_type ar group by ar.art.id, ar.art order by avg(ar.rate_type.id) desc").SetMaxResults(5).List();

            foreach (object[] o in l)
            {
                o[0] = artFactory.GetById((int)o[0], false);
            }

            return l;
        }

    }
}
